/***************************************************************************
 *   Copyright (C) 2005 by Andrzej Oczkowicz                               *
 *   andrew_lz@poczta.fm                                                   *
 *   amg.thc.net.pl                                                        *
 *                                                                         *
 *                                                                         * 
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
 
 /*
 
 	Vision Plus Remote Daemon
 
 */
 
 
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/wait.h> 
#include <signal.h>
#include <pthread.h>

#include "vp_remote.h"



#define CMD_SCRIPT	"/etc/vp_remote.sh"

typedef struct 
{
	int code;
	char *text;
} key;

key codes[33] ={
		{64, "KEY_POWER"}, 
		{44, "KEY_FULLSCREEN"},
		{11, "KEY_0"},
		{2, "KEY_1"},
		{3, "KEY_2"},
		{4, "KEY_3"},
		{5, "KEY_4"},
		{6, "KEY_5"},
		{7, "KEY_6"},
		{8, "KEY_7"},
		{9, "KEY_8"},
		{10, "KEY_9"},
		{102, "KEY_REC"},
		{47, "KEY_FAVORITE"},
		{23, "KEY_REWIND"},
		{49, "KEY_FORWARD"},
		{104, "KEY_UP"},
		{109, "KEY_DOWN"},
		{108, "KEY_LEFT"},
		{103, "KEY_RIGHT"},
		{28, "KEY_PLAY"},
		{107, "KEY_STOP"},
		{46, "KEY_RECALL"},
		{20, "KEY_PAUSE"},
		{50, "KEY_MUTE"},
		{1, "KEY_CANCEL"},
		{25, "KEY_CAPTURE"},
		{37, "KEY_PREVIEW"},
		{18, "KEY_EPG"},
		{38, "KEY_RECORDS"},
		{15, "KEY_TAB"},
		{30, "KEY_TELETEXT"} 
	      } ;

struct run_s
{
	char *script;
	char *param;
};

void error(char *desc)
{
	fprintf(stderr, "VPREMOTE: ERROR %s, sys(%d): %s\n", desc, errno, strerror(errno));
}

void *thread_exec(void *param)
{
	int pid=fork();
	if (pid==0){
		struct run_s *c = param;
		char *dd[3];
		dd[0] = c->script;
		dd[1] = c->param;
		dd[2] = NULL;
		execvp(c->script, dd);
		fprintf(stderr, "error executing: %s, %s!\n", c->script, strerror(errno));
	};
	waitpid(pid, NULL, 0);
	return NULL;
}

struct run_s run;

int execute_script(char *script, char *param)
{
	pthread_t thread;
	run.script = script;
	run.param  = param;
   pthread_create(&thread, NULL, thread_exec, &run);
	return 1;
}


int arg_num(int argc, char *argv[], char *arg_name)
{
  int i;
  for ( i=1; i < argc; i++){
       if ( !strcasecmp(argv[i], arg_name) )
       		return i;
  } 
  return 0;
}

int main(int argc, char *argv[])
{
	#define REMAP(idx, val)	if ( !vp_remap(dev, (idx), (val) ) ) \
					printf("Error vp_remap!\n");

	if ( arg_num(argc, argv, "--help") ) {
		printf("Vision Plus Remote Control Daemon\n"
		       "vpremoted [--cmd COMMAND_FILE] [--dev device] [--hard_lock] [--refresh time] [AS_DAEMON]\n\nCOMMAND_FILE default is "CMD_SCRIPT"\n"
		       "default device is "REMOTE_DEV"\n"
		       "hard_lock - lock device file, default off\n"
		       "time - time interval in ms\n"	       
		      );
		return 0;
	}
	if ( arg_num(argc, argv, "AS_DAEMON") )
		if ( fork() != 0 )
			return 0;	
	int d = arg_num(argc, argv, "--dev");
	char *device;
	if ( d )
		device = argv[d + 1];
	else
		device = REMOTE_DEV;
	int hard_l = arg_num(argc, argv, "--hard_lock");
	int ref = arg_num(argc, argv, "--refresh");
	if ( ref )
		ref = atoi(argv[ref + 1]);
	else
		ref = REF_TIME;
	int cmd = arg_num(argc, argv, "--cmd");
	char *cmdf;
	if ( cmd )
		cmdf = argv[cmd + 1];
	else
		cmdf = CMD_SCRIPT;

	int dev = open(device, OPEN_FLAGS);
	char *cache[256];
	int i;
	for (i=0;i<256;i++) {
		cache[i] = NULL;
		int c;
		for (c=0;c<32;c++)
			if ( codes[c].code == i )
				cache[i] = codes[c].text;
	}	
	int last = 0;
	if ( dev != -1 ) {
		vp_sendcmd(dev, CMD_REMAP_ON);		/* enable remaps */
		vp_sendcmd(dev, CMD_CLEAR_TABLE);
		REMAP( KEY_POWER0, 0 )	/* clear key multicodes */
		REMAP( KEY_POWER1, 0 )
		REMAP( KEY_POWER2, 0 )
		REMAP( KEY_LEFT0, 0 )
		REMAP( KEY_RIGHT0, 0 )
		if ( hard_l )
			vp_sendcmd(dev, CMD_LOCK_DEVICE);
		while ( 1 ) {
			unsigned char cmd = 0;
			int retval = read(dev, &cmd, 1);
			if ( retval && cmd ) {
				if ( ! execute_script(cmdf, cache[cmd]))
					error("excec faild");
			} else {
				usleep( ref * 1000 );
			}
		}
	} else {
		fprintf(stderr, "error opening: %s, %s!\n", device, strerror(errno));
		return 1;
	}
	close(dev);
	return 0;		
}
